from sam import import_csv_path
from sam.util.dbUtil import DB, DEFAULT_PROCESS_DB_CONNECTION_CONFIG
from sam.util.fileUtil2 import read_file, write_file_quick
from sam.util.strUtil import filter_symbol_4_word


class BaseExistCheck(DB):
    def __init(self):
        super().__init__(config=DEFAULT_PROCESS_DB_CONNECTION_CONFIG)

    def do_check(self, table_name: str, column_str: str, need_check_list: list, batch_size: int = 500,
                 optional: str = "str") -> tuple:
        absent_result_list = []
        present_result_list = []
        temp_source_list = []
        for i, source in enumerate(need_check_list):
            temp_source_list.append(source)
            if i > 0 and i % batch_size == 0:
                temp_absent_list, temp_present_list = self.do_query(table_name, column_str, temp_source_list,
                                                                    optional=optional)
                if temp_absent_list:
                    absent_result_list.extend(temp_absent_list)
                if temp_present_list:
                    present_result_list.extend(temp_present_list)
                temp_source_list.clear()
        else:
            temp_absent_list, temp_present_list = self.do_query(table_name, column_str, temp_source_list,
                                                                optional=optional)
            if temp_absent_list:
                absent_result_list.extend(temp_absent_list)
            if temp_present_list:
                present_result_list.extend(temp_present_list)
            temp_source_list.clear()
        return absent_result_list, present_result_list

    def do_query(self, table_name: str, column_str: str, item_list: list, optional: str = "str") -> tuple:
        if "str" == optional:
            return self.query_by_str(table_name, column_str, item_list)
        elif "int" == optional:
            return self.query_by_int(table_name, column_str, item_list)
        else:
            msg = f"暂 仅支持 char 或 int , 不支持 {optional}"
            raise RuntimeError(msg)

    def query_by_int(self, table_name: str, column_str: str, item_list: list) -> tuple:
        pre_item_list_str = ",".join(item_list)
        where_str = f" {column_str} in ({pre_item_list_str}) "
        query_result_list = self.query(
            table_name
            , column_str=f" distinct {column_str} "
            , where=where_str
            , optional="list"
        )
        item_list = [int(item) for item in item_list]
        return self.compare(item_list, query_result_list)

    def query_by_str(self, table_name: str, column_str: str, item_list: list) -> tuple:

        pre_item_list_str = "','".join(item_list)
        where_str = f" {column_str} in ('{pre_item_list_str}') "
        query_result_list = self.query(
            table_name
            , column_str=f" distinct {column_str} "
            , where=where_str
            , optional="list"
            # , is_only_print_sql=True
        )
        return self.compare(item_list, query_result_list)

    @staticmethod
    def compare(item_list: list, query_list: list) -> tuple:
        present_result_list = []
        absent_result_list = []
        if query_list:
            query_result_list = [query[0] for query in query_list]
            if len(query_result_list) == len(item_list):
                present_result_list = query_result_list
                return absent_result_list, present_result_list
            else:
                for i in item_list:
                    if i in query_result_list:
                        present_result_list.append(i)
                    else:
                        absent_result_list.append(i)

                return absent_result_list, present_result_list
        else:
            absent_result_list = item_list
            return absent_result_list, present_result_list


class ExistCheckByFile(BaseExistCheck):
    def __init__(self):
        super().__init__()

    def check_by_file(self, table_name: str, column_str: str, batch_size: int = 500
                      , is_need_pre_formatter: bool = False, target_index: int = 0
                      , export_file_name_suffix: str = None, optional: str = "str"):
        lines = read_file(import_csv_path, is_skip_first_line=False)
        if is_need_pre_formatter:
            item_list = [filter_symbol_4_word(line[target_index]) for line in lines]
        else:
            item_list = [line[target_index] for line in lines]
        new_item_list = list(set(item_list))
        original = len(item_list)
        distinct = len(new_item_list)
        absent_result_list, present_result_list = self.do_check(table_name, column_str, new_item_list, batch_size,
                                                                optional=optional)
        export_absent_list = [[check] for check in absent_result_list]
        write_file_quick(export_absent_list, export_file_name="缺少", prefix=table_name, suffix=export_file_name_suffix)
        export_present_list = [[check] for check in present_result_list]
        write_file_quick(export_present_list, export_file_name="存在", prefix=table_name,
                         suffix=export_file_name_suffix)
        self.logger.info(f"原来有: {original} 条, 去重后有: {distinct} 条")


def demo():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_client_v5_4", column_str="name", target_index=0, batch_size=100)


def demo_2():
    ll = ['1', '2', '3']
    ss = ['2', '3']
    # sss = list(set(ll).difference(set(ss)))
    sss = list(set(ll) ^ set(ss))
    print(sss)


def demo_check():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_yb_report", column_str="yb_name", target_index=0)


def check_sam_client_v5_3():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_client_v5_3", column_str="name", target_index=0)


def check_sam_client_v3():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_data_demo.sam_client_V3", column_str="name", target_index=0)


def check_qcc_address():
    process = ExistCheckByFile()
    process.check_by_file(table_name="qcc_address", column_str="name", target_index=0)


def check_sam_match_4_be():
    process = ExistCheckByFile()
    # process.check_by_file(table_name="sam_data_demo.sam_match", column_str="client_original_name", target_index=0)
    process.check_by_file(table_name="sam_data_demo.sam_match", column_str="wm_match_name", target_index=0)


def check_sam_area():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_area", column_str="name", target_index=0)


def check_sam_client_v5_5_by_id():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_client_v5_5", column_str="id", target_index=0, optional="int")


def check_sam_yb_client_v5_5_by_id():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_yb_client_v5_5", column_str="id", target_index=0, optional="int")


def check_sam_client_v5_5_by_name():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_client_v5_5", column_str="name", target_index=0)


def check_sam_client_v5():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_client_v5", column_str="name", target_index=0)


def check_alias_name_by_alias_name():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_alias_map", column_str="alias_name", target_index=0)


def check_alias_name_by_standard_name():
    process = ExistCheckByFile()
    process.check_by_file(table_name="sam_alias_map", column_str="standard_name", target_index=0)


if __name__ == "__main__":
    check_sam_client_v5_5_by_name()
